package ils.util;

import org.marc4j.MarcReader;
import org.marc4j.MarcStreamReader;
import org.marc4j.marc.ControlField;
import org.marc4j.marc.DataField;
import org.marc4j.marc.Record;
import org.marc4j.marc.VariableField;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * User: rejeev
 * Date: 8/23/14
 */
public class MarcLoader {
    private Connection connection;
    private int maxId;

    public MarcLoader() throws Exception {
        Class.forName("com.mysql.jdbc.Driver").newInstance();
        //Connection connection = DriverManager.getConnection("jdbc:mysql://localhost/test?" +
        //        "user=monty&password=greatsqldb");
        connection = DriverManager.getConnection("jdbc:mysql://localhost/test");
    }

    public static void main(String[] args) throws Exception {
        new MarcLoader().process(args[0]);
    }

    private void process(String dir) throws Exception {
        List<File> fileNames = getFileNames(dir);
        maxId = getMaxId();
        for(File file : fileNames) {
            read(file);
        }
        connection.close();
    }

    private List<File> getFileNames(String dirName) throws Exception {
        File dir = new File(dirName);
        File[] files = dir.listFiles();
        List<File> fileList = new ArrayList<>();
        for(File file : files){
            if(file.isFile()) fileList.add(file);
        }
        return fileList;
    }

    public void read(File file) throws Exception {
        InputStream inputStream = new FileInputStream(file);
        if(inputStream == null) {
            System.out.println("Specified file is not present; file=" + file.getName());
            return;
        }

        MarcReader reader = new MarcStreamReader(inputStream);
        while (reader.hasNext()){
            String title = null;
            String author = null;
            String publisher = null;
            String publishYear = null;
            String language = null;

            Record record = reader.next();
            //System.out.println(record.toString());
            DataField field = (DataField)record.getVariableField("100");
            if(field != null) {
                author = field.getSubfield('a').getData();
                System.out.println("Author: " + author);
            }
            DataField titleField = (DataField)record.getVariableField("245");
            if(titleField != null){
                title = titleField.getSubfield('a').getData();
                if(title.length() > 254) title = title.substring(0, 253);
                System.out.println("Title: " + title);
            }
            DataField publisherField = (DataField)record.getVariableField("260");
            if(publisherField != null){
                publisher = publisherField.getSubfield('b').getData();
                publishYear = publisherField.getSubfield('c').getData();
                System.out.println("publisher: " + publisher + ", date: " + publishYear);
            }
            List<VariableField> subjectFields = record.getVariableFields("653");
            List<String> subjectList = new ArrayList<>();
            for(VariableField subjectField : subjectFields){
                String subject = ((DataField)subjectField).getSubfield('a').getData();
                subjectList.add(subject);
            }
            System.out.println(subjectList);
            ControlField languageField = (ControlField)record.getVariableField("008");
            language = languageField.getData().substring(35,38);
            System.out.println("Language: " + language);

            maxId++;
            insertBook(title, author, publisher, publishYear, language, maxId);
            for(String subject : subjectList){
                insertSubject(subject, maxId);
            }
        }
        //connection.close();
    }

    private int getMaxId() throws Exception {
        Statement statement = connection.createStatement();
        ResultSet resultSet = statement.executeQuery("select max(id) from books");
        if(resultSet.next()) {
            int maxId = resultSet.getInt(1);
            return maxId;
        }
        return 0;
    }

    private void insertBook(String title, String author, String publisher, String publishYear, String language, int id) throws Exception {
        String sql = "insert into books (id, title, author, publisher, publishYear, lang) values(?, ?, ?, ?, ?, ?)";
        PreparedStatement preparedStatement = connection.prepareStatement(sql);
        preparedStatement.setInt(1, id);
        preparedStatement.setString(2, title);
        preparedStatement.setString(3, author);
        preparedStatement.setString(4, publisher);
        preparedStatement.setString(5, publishYear);
        preparedStatement.setString(6, language);
        preparedStatement.executeUpdate();
        preparedStatement.close();
    }

    private void insertSubject(String subject, int bookId) throws Exception {
        String sql = "insert into book_topics (bookId, topicName) values(?, ?)";
        PreparedStatement preparedStatement = connection.prepareStatement(sql);
        preparedStatement.setInt(1, bookId);
        preparedStatement.setString(2, subject);
        preparedStatement.executeUpdate();
        preparedStatement.close();
    }
}
